package cn.com.sinux.spring.utils.fileconvert;

import cn.com.sinux.spring.commons.SystemConfig;
import cn.com.sinux.spring.exception.BusinessException;
import cn.com.sinux.spring.exception.ServiceException;
import cn.com.sinux.spring.utils.FileUtils;
import org.apache.commons.io.filefilter.FileFileFilter;
import org.apache.commons.lang.StringUtils;
import org.icepdf.core.pobjects.MyDocument;
import org.icepdf.core.pobjects.Page;
import org.icepdf.core.util.GraphicsRenderingHints;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;

/**
 * Created by Administrator on 2014/7/10.
 */
public abstract class ConvertEngine {

    public static enum EngineType {
        OPENOFFICE,
        PDFCREATOR,
        POI
    }

    public static enum EngineConfig {
        OPENOFFICE_HOME,
        OPENOFFICE_PORT,
        PDFCREATOR_HOME
    }

    private static Map<EngineType, ConvertEngine> convertEngine = new HashMap<EngineType, ConvertEngine>() {
    };

    public static void doConvert(EngineType engineType, ConvertType convertType, ConvertObject convertObject,
                                 Map<EngineConfig, String> map) {
        try {
            ConvertEngine engine = convertEngine.get(engineType);
            if (engine == null) {
                if (EngineType.OPENOFFICE.equals(engineType)) {
                    if (StringUtils.isBlank(map.get(EngineConfig.OPENOFFICE_HOME))
                            || StringUtils.isBlank(map.get(EngineConfig.OPENOFFICE_PORT))) {
                        throw new ServiceException("未设置openoffice的转换路径");
                    }
                    engine = new OpenOfficeConvertEngine(map.get(EngineConfig.OPENOFFICE_HOME), Integer.valueOf(map.get(EngineConfig.OPENOFFICE_PORT)));
                    convertEngine.put(EngineType.OPENOFFICE, engine);
                } else if (EngineType.PDFCREATOR.equals(engineType)) {
                    if (StringUtils.isBlank(map.get(EngineConfig.PDFCREATOR_HOME))) {
                        throw new ServiceException("未设置pdfcreator的转换路径");
                    }
                    engine = new PDFCreatorConvertEngine(map.get(EngineConfig.PDFCREATOR_HOME));
                    convertEngine.put(EngineType.PDFCREATOR, engine);
                } else {
                    engine = new POIConvertEngine();
                    convertEngine.put(EngineType.POI, engine);
                }
            }
            engine.convert(convertType, convertObject);
        } catch (Exception e) {
            throw new BusinessException("抓换文件失败");
        }
    }

    public String pdf2Swf(String sourcePath, String destPath, boolean delSource) throws Exception {
        File dest = new File(destPath);
        if (!dest.exists())
            dest.mkdirs();
        // 源文件不存在则返回
        File source = new File(sourcePath);
        if (!source.exists())
            throw new IOException("转换失败");
        String fileName = UUID.randomUUID().toString() + ".swf";
        // 调用pdf2swf命令进行转换
        String _dest = destPath + "/" + fileName;
        String command = SystemConfig.getProperty("root.path") + "/pdf2swf.exe " + sourcePath + " -o "
                + _dest + " -f -T 9";
        Process process = Runtime.getRuntime().exec(command);
//写一个while死循环检查UN文件是否执行完成
        int i = 0;
        //每隔15秒检查一次文件，直到文件退出或者5分钟没有就直接退出
        while (i < 1000 * 60 * 5) {
            if (new File(_dest).exists()) {
                if (delSource && source.delete()) {
                    process.destroy();
                    return fileName;
                }
            }
            Thread.sleep(15000);
            i += 15000;
        }
        LoggerFactory.getLogger(ConvertEngine.class).error("抓换swf失败，异常原因");
        process.destroy();
        return fileName;
    }

    public List<String> pdf2Img(String source, String dest) throws Exception {
        MyDocument document = new MyDocument();
        document.setFile(source);
        int maxPages = document.getPageTree().getNumberOfPages();
        List<String> imgString = new ArrayList<String>(maxPages);
        FileOutputStream outputStream = null;
        try {
            for (int i = 0; i < maxPages; i++) {
                BufferedImage img = (BufferedImage) document.getPageImage(i,
                        GraphicsRenderingHints.SCREEN, Page.BOUNDARY_CROPBOX, 0f,
                        2f);
                String name = UUID.randomUUID().toString() + ".png";
                outputStream = new FileOutputStream(dest + File.separator + name);
                ImageIO.write(img, "png", outputStream);
                imgString.add(name);
            }
        } catch (IOException ioex) {
            throw new BusinessException("转换图片失败");
        } finally {
            if (outputStream != null) {
                outputStream.close();
                outputStream = null;
            }
        }
        return imgString;
    }

    public static enum DocType {
        doc,
        docx,
        xls,
        xlsx,
        ppt,
        pptx
    }

    public static enum ConvertType {
        toHtml,
        toImage,
        toPdf,
        toSwf
    }

    public static enum ConvertResultType {
        PNG,
        PDF,
        HTML,
        SWF
    }

    public static enum ConvertStatus {
        CONVERTING,
        FAILURE,
        SUCCESS
    }

    /**
     * @param convertType
     * @return
     */
    public abstract void convert(ConvertType convertType, ConvertObject convertObject) throws Exception;
}
